home *** CD-ROM | disk | FTP | other *** search
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <exec/libraries.h>
- #include <intuition/intuition.h>
- #include <intuition/intuitionbase.h>
- #include <intuition/screens.h>
- #include <graphics/gfx.h>
- #include <graphics/text.h>
- #include <graphics/gfxmacros.h>
- #include <clib/macros.h>
- #include <clib/exec_protos.h>
- #include <clib/intuition_protos.h>
- #include <clib/graphics_protos.h>
-
- void sprintf (void *,...);
-
- #define DEMO FALSE
-
- #define PATTERN TRUE
- #define WINDOW TRUE
- #define MULTIDRAW TRUE
-
- #if MULTIDRAW
- #define PolyDraw MultiDraw
- #endif
-
- #define NUMPOINTS 5L
- #define TOTPOINTS (NUMPOINTS * 2L)
- #define SHIFTED (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)
-
- struct Cursor
- {
- struct Window *cs_Win; /* Coordinate window */
- struct TextFont *cs_Font; /* Font to use */
- ULONG cs_IDCMP; /* Previous IDCMP settings */
- ULONG cs_WinFlags; /* Previous window flags */
- UWORD cs_Points[TOTPOINTS]; /* Cursor point array */
- UWORD cs_Pattern; /* Pattern to use for cursor */
-
- /* These could easily be flags */
- SHORT cs_Mode; /* Drawing mode */
- BOOL cs_Drag; /* Dragging cursor? */
- BOOL cs_Going; /* Doing cursor? */
- BOOL cs_Keyboard; /* Done with mouse, now by key? */
-
- /* Text positioning information */
- WORD cs_Left, cs_Line1, cs_Line2;
-
- BYTE cs_Buffer[8]; /* Coordinate buffer */
- struct NewWindow cs_NW; /* Our own NewWindow */
- struct IBox cs_Box; /* Cursor rectangle */
- };
-
- /* dtcursor.c */
- VOID MultiDraw (struct RastPort *rp, LONG num, Point *xy);
- struct Cursor *AllocAnts (struct TextAttr * tattr);
- VOID FreeAnts (struct Cursor * cs);
- BOOL WhereIsMouse (struct IntuiMessage * msg, struct Cursor * cs);
- VOID AbortCut (struct Window * win, struct Cursor * cs);
- struct IBox *DoButtons (struct Window * win, struct IntuiMessage * msg, struct Cursor * cs);
- struct IBox *DoMouseMove (struct Window * win, struct IntuiMessage * msg, SHORT xadj, SHORT yadj, struct Cursor * cs);
- VOID AdjUpperLeft (SHORT xadj, SHORT yadj, struct Cursor * cs);
- VOID SetUpperLeft (struct IntuiMessage * msg, struct Cursor * cs);
- VOID AdjLowerRight (SHORT xadj, SHORT yadj, struct Cursor * cs);
- VOID SetLowerRight (struct IntuiMessage * msg, struct Cursor * cs);
- VOID ShowCoords (struct Window * win, struct Cursor * cs);
-
- #define WWIDTH 72
- #define WHEIGHT 24
-
- static struct NewWindow Coord =
- {
- 0, 0, WWIDTH, WHEIGHT, /* Window dimensions */
- 0, 0, /* No detail or block */
- CLOSEWINDOW, /* No IDCMP port */
- BORDERLESS | NOCAREREFRESH | REPORTMOUSE,
- NULL, NULL, NULL,
- NULL, /* Screen... */
- NULL,
- 0, 0, 0, 0,
- WBENCHSCREEN /* For now... */
- };
-
- static struct TextAttr TOPAZ80 =
- {(STRPTR) "topaz.font", TOPAZ_EIGHTY, 0, 0};
-
- VOID MultiDraw (struct RastPort *rp, LONG num, Point *xy)
- {
- register Point *coord = xy;
- register LONG i, j = (num - 1);
-
- for (i = 0L; i < j; i++)
- {
- Move(rp, (LONG)coord->x, (LONG)coord->y);
- coord++;
- Draw(rp, (LONG)coord->x, (LONG)coord->y);
- }
- }
-
- struct Cursor *AllocAnts (struct TextAttr * tattr)
- {
- extern struct Library *IntuitionBase;
- struct Cursor *cs;
-
- /* Allocate our record */
- if (cs = (struct Cursor *) AllocVec (sizeof (struct Cursor), MEMF_CLEAR))
- {
- register SHORT i;
-
- #if WINDOW
- /* We can only use the font if using 2.0 */
- if (IntuitionBase->lib_Version >= 36)
- {
- struct TextAttr *attr = tattr;
-
- /* Copy the NewWindow from the template */
- cs->cs_NW = *(&Coord);
-
- /* Did they provide a font? */
- if (attr == NULL)
- {
- /* Use topaz 8 */
- attr = &(TOPAZ80);
- }
-
- /* Open the font */
- if (cs->cs_Font = OpenFont (attr))
- {
- struct TextFont *f = cs->cs_Font;
- struct RastPort rp;
-
- InitRastPort (&rp);
- SetFont (&rp, f);
-
- /* Probably not the most intelligent way of getting the width,
- * (especially when dealing with proportional fonts) ... */
- cs->cs_NW.Width = TextLength (&rp, " 999,999 ", 9) + 2;
- cs->cs_NW.Height = (f->tf_YSize * 2) + 5;
-
- cs->cs_Left = TextLength (&rp, " ", 1);
- cs->cs_Line1 = 2 + f->tf_Baseline;
- cs->cs_Line2 = 1 + f->tf_YSize + cs->cs_Line1;
- }
- }
- #endif
-
- /* Initialize the record */
- #if PATTERN
- cs->cs_Pattern = 0xF0F0;
- #else
- cs->cs_Pattern = 0xFFFF;
- #endif
- cs->cs_Drag = FALSE;
- cs->cs_Going = FALSE;
- cs->cs_Keyboard = FALSE;
- cs->cs_Mode = 0;
-
- /* Clear the array */
- for (i = 0; i < TOTPOINTS; i++)
- {
- cs->cs_Points[i] = 0;
- }
-
- /* Clear the box */
- cs->cs_Box.Left = 0;
- cs->cs_Box.Top = 0;
- cs->cs_Box.Width = 0;
- cs->cs_Box.Height = 0;
- }
-
- return (cs);
- }
-
- VOID FreeAnts (struct Cursor * cs)
- {
-
- /* Make sure we have a record */
- if (cs)
- {
- if (cs->cs_Win)
- {
- CloseWindow (cs->cs_Win);
- cs->cs_Win = NULL;
- }
-
- /* Font open? */
- if (cs->cs_Font)
- {
- /* Close the font */
- CloseFont (cs->cs_Font);
- }
-
- /* Free the record */
- FreeVec (cs);
- }
- }
-
- VOID
- ShowCoords (struct Window * win, struct Cursor * cs)
- {
-
- if (win)
- {
- struct IBox *box = &(cs->cs_Box);
- struct Screen *scr = win->WScreen;
- struct IntuiMessage *msg;
-
- /* Move the little window around */
- ChangeWindowBox (win,
- (scr->MouseX + 10), (scr->MouseY - win->Height),
- win->Width, win->Height);
-
- /* Print the width & height */
- sprintf (cs->cs_Buffer, "%3d,%3d", box->Width, box->Height);
- Move (win->RPort, cs->cs_Left, cs->cs_Line2);
- Text (win->RPort, cs->cs_Buffer, 7);
-
- /* Clear out any outstanding messages. */
- while (msg = (struct IntuiMessage *) GetMsg (win->UserPort))
- {
- ReplyMsg ((struct Message *) msg);
- }
- }
- }
-
- VOID AbortCut (struct Window * win, struct Cursor * cs)
- {
- /* Is the cursor active? */
- if (cs->cs_Going)
- {
- struct RastPort crp = *win->RPort;
-
- /* No mask... */
- crp.Mask = ~0;
-
- SetDrMd (&crp, COMPLEMENT);
- SetDrPt (&crp, cs->cs_Pattern);
- Move (&crp, cs->cs_Points[0], cs->cs_Points[1]);
- PolyDraw (&crp, NUMPOINTS, (Point *)&(cs->cs_Points[0]));
- }
-
- /* Is the coordinate window open? */
- if (cs->cs_Win)
- {
- /* Close it */
- CloseWindow (cs->cs_Win);
- cs->cs_Win = NULL;
- }
-
- /* Clear stuff */
- cs->cs_Drag = cs->cs_Keyboard = cs->cs_Going = FALSE;
- cs->cs_Mode = 0;
- }
-
- VOID BoundCheckMouse (struct IntuiMessage * msg, struct Cursor * cs)
- {
- struct Window *win = msg->IDCMPWindow;
-
- /* Freshen the values */
- msg->MouseX = win->MouseX;
- msg->MouseY = win->MouseY;
-
- /* Make sure mouse is in the window */
- {
- WORD tx = win->BorderLeft;
- WORD ty = win->BorderTop;
- WORD bx = win->Width - win->BorderRight - 1;
- WORD by = win->Height - win->BorderBottom - 1;
-
- /* Range check the horizontal value */
- if (msg->MouseX < tx)
- msg->MouseX = tx;
- else if (msg->MouseX > bx)
- msg->MouseX = bx;
-
- /* Range check the vertical value */
- if (msg->MouseY < ty)
- msg->MouseY = ty;
- else if (msg->MouseY > by)
- msg->MouseY = by;
- }
- }
-
- VOID UpdateBox (struct Cursor * cs)
- {
-
- /* Revise the box */
- cs->cs_Box.Left = MIN (cs->cs_Points[0], cs->cs_Points[4]);
- cs->cs_Box.Top = MIN (cs->cs_Points[1], cs->cs_Points[5]);
- cs->cs_Box.Width = MAX (cs->cs_Points[0], cs->cs_Points[4]);
- cs->cs_Box.Height = MAX (cs->cs_Points[1], cs->cs_Points[5]);
- cs->cs_Box.Width = cs->cs_Box.Width - cs->cs_Box.Left + 1;
- cs->cs_Box.Height = cs->cs_Box.Height - cs->cs_Box.Top + 1;
- }
-
- struct IBox *
- DoButtons (struct Window * win, struct IntuiMessage * msg, struct Cursor * cs)
- {
- /* Freshen & revise the coordinates */
- BoundCheckMouse (msg, cs);
-
- switch (msg->Code)
- {
- case SELECTDOWN:
-
- /* See if the cursor is already active */
- if (cs->cs_Going)
- {
- /* Turn it off */
- AbortCut (win, cs);
- }
-
- /* Set coordinates */
- SetUpperLeft (msg, cs);
- SetLowerRight (msg, cs);
-
- /* Revise the box */
- UpdateBox (cs);
-
- /* Draw the first frame */
- {
- struct RastPort crp = *win->RPort;
-
- /* No mask... */
- crp.Mask = ~0;
-
- SetDrMd (&crp, COMPLEMENT);
- Move (&crp, cs->cs_Points[0], cs->cs_Points[1]);
- PolyDraw (&crp, NUMPOINTS, (Point *)&(cs->cs_Points[0]));
- }
-
- /* Set some pertinant values */
- cs->cs_Drag = TRUE;
- cs->cs_Going = TRUE;
- cs->cs_Keyboard = FALSE;
- cs->cs_Mode = 1;
-
- /* Do we need to do a coordinate window? */
- if ((cs->cs_Win == NULL) && cs->cs_Font)
- {
- struct Screen *scr = win->WScreen;
- struct IBox *box = &(cs->cs_Box);
-
- /* Adjust the upper-left */
- cs->cs_NW.LeftEdge = (scr->MouseX + 10);
- cs->cs_NW.TopEdge = (scr->MouseY - cs->cs_NW.Height);
- cs->cs_NW.Type = CUSTOMSCREEN;
- cs->cs_NW.Screen = scr;
-
- if (cs->cs_Win = OpenWindowTags (&(cs->cs_NW),
- WA_AutoAdjust, TRUE,
- TAG_DONE))
- {
- /* Clear the area */
- SetRast (cs->cs_Win->RPort, 1);
- SetAPen (cs->cs_Win->RPort, 2);
- RectFill (cs->cs_Win->RPort,
- 1, 1, (cs->cs_Win->Width - 2), (cs->cs_Win->Height - 2));
-
- /* Make it readable */
- SetAPen (cs->cs_Win->RPort, 1);
- SetBPen (cs->cs_Win->RPort, 2);
- SetDrMd (cs->cs_Win->RPort, JAM2);
- SetFont (cs->cs_Win->RPort, cs->cs_Font);
-
- /* Print the upper-left coordinates */
- sprintf (cs->cs_Buffer, "%3d,%3d",
- (box->Left - win->BorderLeft),
- (box->Top - win->BorderTop));
- Move (cs->cs_Win->RPort, cs->cs_Left, cs->cs_Line1);
- Text (cs->cs_Win->RPort, cs->cs_Buffer, 7);
- }
- }
-
- /* Show the coordinates */
- ShowCoords (cs->cs_Win, cs);
-
- /* Save & modify the window flags */
- cs->cs_IDCMP = win->IDCMPFlags;
- cs->cs_WinFlags = win->Flags;
- win->Flags |= RMBTRAP;
- break;
-
- case MENUDOWN:
- /* See if the cursor is already active */
- if (cs->cs_Going)
- {
- /* Turn it off */
- AbortCut (win, cs);
- }
-
- /* Restore the window flags */
- if (!(cs->cs_WinFlags & RMBTRAP))
- {
- win->Flags &= ~RMBTRAP;
- }
- break;
-
- case SELECTUP:
- /* set the bounding box rectangle if we where doing bounds */
- if (cs->cs_Mode == 1)
- {
- /* Revise the box */
- UpdateBox (cs);
- }
-
- /* Clear some values */
- cs->cs_Drag = FALSE;
- cs->cs_Keyboard = TRUE;
- cs->cs_Mode = 2;
-
- /* Restore the window flags */
- if (!(cs->cs_WinFlags & RMBTRAP))
- {
- win->Flags &= ~RMBTRAP;
- }
-
- if (cs->cs_Win)
- {
- CloseWindow (cs->cs_Win);
- cs->cs_Win = NULL;
- }
-
-
- break;
- }
-
- return (&(cs->cs_Box));
- }
-
- struct IBox *
- DoMouseMove (struct Window * win, struct IntuiMessage * msg,
- SHORT xadj, SHORT yadj, struct Cursor * cs)
- {
- #if PATTERN
- if (cs->cs_Going)
- #else
- if (cs->cs_Drag)
- #endif
- {
- struct RastPort crp;
- USHORT dir;
-
- /* Copy the RastPort */
- crp = *(win->RPort);
- crp.Mask = ~0;
-
- /* Check the mouse coordinates */
- BoundCheckMouse (msg, cs);
-
- /* Erase the prior image */
- SetDrMd (&crp, COMPLEMENT);
- SetDrPt (&crp, cs->cs_Pattern);
- Move (&crp, cs->cs_Points[0], cs->cs_Points[1]);
- PolyDraw (&crp, NUMPOINTS, (Point *)&(cs->cs_Points[0]));
-
- #if PATTERN
- /* Get the direction that we're traveling */
- dir = ((cs->cs_Points[0] < cs->cs_Points[2]) ||
- (cs->cs_Points[1] > cs->cs_Points[5])) ? 0 : 1;
-
- /* Adjust the ants according to direction */
- if (dir)
- {
- cs->cs_Pattern = ((cs->cs_Pattern << 1) & 0xfffe) |
- ((cs->cs_Pattern & 0x8000) >> 15);
- }
- else
- {
- cs->cs_Pattern = ((cs->cs_Pattern >> 1) & 0x7fff) |
- ((cs->cs_Pattern & 1) << 15);
- }
- #endif
-
- if ((xadj && yadj) || cs->cs_Keyboard)
- {
- if (msg->Qualifier & SHIFTED)
- AdjLowerRight (xadj, yadj, cs);
- else
- AdjUpperLeft (xadj, yadj, cs);
- }
- else
- {
- SetLowerRight (msg, cs);
- }
-
- /* Draw the new ants */
- SetDrPt (&crp, cs->cs_Pattern);
- Move (&crp, cs->cs_Points[0], cs->cs_Points[1]);
- PolyDraw (&crp, NUMPOINTS, (Point *)&(cs->cs_Points[0]));
-
- /* Update the box */
- if (cs->cs_Mode == 1)
- {
- /* Revise the box */
- UpdateBox (cs);
- }
- }
-
- if (cs->cs_Drag)
- {
- ShowCoords (cs->cs_Win, cs);
- }
-
- return (&(cs->cs_Box));
- }
-
- VOID AdjUpperLeft (SHORT xadj, SHORT yadj, struct Cursor * cs)
- {
-
- cs->cs_Points[0] += xadj;
- cs->cs_Points[6] = cs->cs_Points[8] = cs->cs_Points[0];
-
- cs->cs_Points[1] += yadj;
- cs->cs_Points[3] = cs->cs_Points[9] = cs->cs_Points[1];
- }
-
- VOID SetUpperLeft (struct IntuiMessage * msg, struct Cursor * cs)
- {
-
- cs->cs_Points[0] = cs->cs_Points[2] = msg->MouseX;
- cs->cs_Points[4] = cs->cs_Points[6] = msg->MouseX;
- cs->cs_Points[8] = msg->MouseX;
-
- cs->cs_Points[1] = cs->cs_Points[3] = msg->MouseY;
- cs->cs_Points[5] = cs->cs_Points[7] = msg->MouseY;
- cs->cs_Points[9] = msg->MouseY;
- }
-
- VOID AdjLowerRight (SHORT xadj, SHORT yadj, struct Cursor * cs)
- {
-
- cs->cs_Points[2] += xadj;
- cs->cs_Points[4] = cs->cs_Points[2];
-
- cs->cs_Points[5] += yadj;
- cs->cs_Points[7] = cs->cs_Points[5];
- }
-
- VOID SetLowerRight (struct IntuiMessage * msg, struct Cursor * cs)
- {
-
- cs->cs_Points[2] = cs->cs_Points[4] = msg->MouseX;
- cs->cs_Points[5] = cs->cs_Points[7] = msg->MouseY;
- }
-